﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using ControlCenter.ApplicationService.Services.Utility;
using ControlCenter.Model;
using ControlCenter.Model.WebApiDto;
using ControlCenter.Operation;
using Microsoft.AspNetCore.Http;
using MingYuanYun.Context.Abstractions;
using MingYuanYun.Exception;
using MingYuanYun.Utility;

namespace ControlCenter.ApplicationService.Services
{
    /// <summary>
    /// 文档服务类
    /// </summary>
    public class FileService : ApplicationServiceBase, IFileService
    {
        private static readonly string[] AllowNupkgExts = new string[] { ".nupkg" };
        private static readonly string[] AllowRobotExts = new string[] { ".zip" };
        private readonly string _uploadFileSavePath;

        /// <summary>
        /// 类初始化
        /// </summary>
        /// <param name="context"></param>
        public FileService(IServiceContext context) : base(context)
        {
            _uploadFileSavePath = this.GetConfig<string>("PackageSavePath");
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="file"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public async Task<UploadNupkgFileReturnDto> UploadPackage(IFormFile file, string type)
        {
            //参数校验
            if (file == null)
            {
                throw new BusinessException("上传内容不能为空");
            }
            if (file.Length <= 0)
            {
                throw new BusinessException($"上传的文件大小不能为0");
            }

            try
            {
                if (type == "robot")
                {
                    return await UploadRobot(file);
                }
                else
                {
                    return await UploadNupkg(file);
                }
            }
            catch (BusinessException be)
            {
                throw be;
            }
            catch (Exception e)
            {
                throw new BusinessException(e.Message);
            }
            
        }

        /// <summary>
        /// 上传应用包
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        private async Task<UploadNupkgFileReturnDto> UploadNupkg(IFormFile file)
        {
            if (!IsAllowNupkgExt(Path.GetExtension(file.FileName)))
            {
                throw new BusinessException($"不支持上传 {Path.GetExtension(file.FileName)} 文件格式。");
            }
            

            //生成文件路径
            var tempPhysicsSavePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _uploadFileSavePath, "temp");
            var tempPhysicsFilename = $"{tempPhysicsSavePath}\\{file.FileName}"; //临时存放路径
            var downloadUrl = $"/{_uploadFileSavePath}/temp/{file.FileName}";

            //保存文件
            Utils.CreateDirectory(tempPhysicsSavePath);
            Utils.DeleteFile(tempPhysicsFilename);
            using (var fileStream = new FileStream(tempPhysicsFilename, FileMode.Create))
            {
                await file.CopyToAsync(fileStream);
            }

            //解析nupkg文件信息
            var nupkgInfo = await NupkgFile.ReadNuspec(tempPhysicsFilename);

            //组装返回DTO数据
            UploadNupkgFileReturnDto returnDto = new UploadNupkgFileReturnDto
            {
                FileName = file.FileName,
                NupkgName = nupkgInfo.id,
                Version = nupkgInfo.version,
                FileSize = (int)(file.Length / 1024),
                UploadTime = DateTime.Now,
                Url = downloadUrl
            };

            return returnDto;
        }

        /// <summary>
        /// 上传机器人包
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        private async Task<UploadNupkgFileReturnDto> UploadRobot(IFormFile file)
        {
            if (!IsAllowRobotExt(Path.GetExtension(file.FileName)))
            {
                throw new BusinessException($"不支持上传 {Path.GetExtension(file.FileName)} 文件格式。");
            }

            //生成文件路径
            var tempPhysicsSavePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _uploadFileSavePath, "temp");
            var tempPhysicsFilename = $"{tempPhysicsSavePath}\\{file.FileName}"; //临时存放路径
            var downloadUrl = $"/{_uploadFileSavePath}/temp/{file.FileName}";

            //保存文件
            Utils.CreateDirectory(tempPhysicsSavePath);
            Utils.DeleteFile(tempPhysicsFilename);
            using (var fileStream = new FileStream(tempPhysicsFilename, FileMode.Create))
            {
                await file.CopyToAsync(fileStream);
            }
            
            //组装返回DTO数据
            UploadNupkgFileReturnDto returnDto = new UploadNupkgFileReturnDto
            {
                FileName = file.FileName,
                NupkgName = file.FileName,
                Version = ParseVersion(file.FileName),
                FileSize = (int)(file.Length / 1024),
                UploadTime = DateTime.Now,
                Url = downloadUrl
            };

            return returnDto;
        }

        #region 私有方法
        /// <summary>
        /// 检查文件扩展名是否允许上传
        /// </summary>
        /// <param name="fileExt">文件扩展名，如：.zip</param>
        /// <returns></returns>
        private bool IsAllowNupkgExt(string fileExt)
        {
            foreach (var allowExt in AllowNupkgExts)
            {
                if (string.Equals(fileExt, allowExt, StringComparison.CurrentCultureIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 检查文件扩展名是否允许上传
        /// </summary>
        /// <param name="fileExt">文件扩展名，如：.zip</param>
        /// <returns></returns>
        private bool IsAllowRobotExt(string fileExt)
        {
            foreach (var allowExt in AllowRobotExts)
            {
                if (string.Equals(fileExt, allowExt, StringComparison.CurrentCultureIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 从文件名中解析出版本号，如 Robot.1.0.1.zip 返回1.0.1
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        private string ParseVersion(string filename)
        {
            var match = Regex.Match(filename, "[\\d.]+");
            if (match.Success)
            {
                return match.Value.Trim('.');
            }
            return string.Empty;
        }
        #endregion
    }
}
